package com.gjt.urlConnection;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;

/**
 * Created with Intel IDEA.
 * URLConnection:抽象类表示指向URL指定的活动链接； 仅有一个构造函数为保护型protected URLConnection(URL url)
 *      第一次构造URLConnection 是它是未连接的，调用connect
 *
 *      URLConnection 提供了对HTTP首部的访问；可以配置发送服务器的请求参数；还可以向服务器写数据
 *
 *      获取http指定的首部字段方法：
 *          getContentType: 返回响应主体的mime内容类型（包含编码方式）
 *          getContentLength(): 获取内容有多少个字节,没有就返回-1
 *          getContentLengthLong(): 获取内容有多少个字节(范围更大),没有就返回-1
 *          getContentEncoding(): 指出内容是如何编码的
 *          getDate(): 获取文档最后的修改时间
 *          getExpiration(): 指示应当何时从缓存种删除文档，并从服务器重新下载
 *          getLastModified(): 获取文档最后的修改时间
 *          getHeaderField(int i): 返回第N个首部字段的值
 *          getHeaderField(String name): 返回指定首部字段的值 不一定是有效值 必须判空
 *          getHeaderFieldKey(int i): 返回第N个的首部的键
 *          getHeaderFieldDate(String name, long Default):  获取表示日期的首部字段，如果参数中解析不出来 就返回默认的0； expires,last-modified,date
 *          getHeaderFieldInt(String name, int Default):
 *
 * @Auther: gjt
 * @Date: 2024/3/24 14:31
 */
public class URLConnections {

    /**
     *  读取服务器的数据 使用URLConnection
     */
    private static void readUrlConnection(){
        try{
            URL url = new URL("http://gjt1314yy.xyz");
            // Url的openStream() 只是从自己的URLConnection对象中返回一个InputStream
            URLConnection urlConnection = url.openConnection();
            try(BufferedReader buf = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))){
                char[] list = new char[1024];
                int c;
                while((c = buf.read(list)) !=-1){
                    System.out.println(list);
                }
            }catch (IOException e){
                e.printStackTrace();
            }

        }catch (IOException e) {
            throw new RuntimeException(e);
        }

        String file ="E:\\a.log\\test.bin";
    }

    /**
     *
     * 用正确的字符集下载一个web网页
     */
    private static void readConnection(){
        try{
            // 设置默认的编码方式
            String encoding ="UTF-8";
            URL url = new URL("http://gjt1314yy.xyz");
            // Url的openStream() 只是从自己的URLConnection对象中返回一个InputStream
            URLConnection urlConnection = url.openConnection();
            String contentType = urlConnection.getContentType();
            int encodingStart = contentType.indexOf("charset=");
            if(encodingStart != -1){
                encoding= contentType.substring(encodingStart+8);
            }

            try(BufferedReader buf = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(),encoding))){
                char[] list = new char[1024];
                int c;
                while((c = buf.read(list)) !=-1){
                    System.out.println(list);
                }
            }catch (IOException e){
                e.printStackTrace();
            }

        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * 读取二进制文件
     */
    private static void readBinFile(){

        try{
            URL url = new URL("  http://gjt1314yy.xyz/data/text.bin");
            URLConnection urlConnection = url.openConnection();
            String contentType = urlConnection.getContentType();
            int contentLength = urlConnection.getContentLength();
            // 指出内容是如何编码的
            String contentEncoding = urlConnection.getContentEncoding();

            // 获取文档的发出时间
            long date = urlConnection.getDate();
            Date date1 = new Date(date);
            System.out.println("文档发出时间是："+date1);

            // 指示应当何时从缓存种删除文档，并从服务器重新下载
            long expiration = urlConnection.getExpiration();
            System.out.println("文档过期时间是："+ new Date(expiration));

            // 获取文档最后的修改时间
            long lastModified = urlConnection.getLastModified();
            System.out.println("文档最后的修改时间是："+ new Date(lastModified));

            if(contentType.startsWith("text/") || contentLength == -1){
                throw new IOException("This is not a binary file");
            }
            try(InputStream buf = urlConnection.getInputStream()){
                byte[] list = new byte[contentLength];
                int offset= 0;

                // 保证一次性返回contentLength 字节；
                while (offset < contentLength){
                    int read = buf.read(list, offset, contentLength - offset);
                    if(read == -1)break;
                    offset += read;
                }

                if(offset != contentLength){
                    throw  new IOException("Only read "+ offset + "bytes; Expected "+ contentLength + " bytes");
                }

                String filename =  "E:\\a.log\\test.bin";
                try (FileOutputStream out = new FileOutputStream(filename)){
                    out.write(list);
                    out.flush();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }catch (MalformedURLException e){
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取http首部
     */
    private static void readHttpHead(){
        try{
            URL url = new URL("http://gjt1314yy.xyz");
            // Url的openStream() 只是从自己的URLConnection对象中返回一个InputStream
            URLConnection urlConnection = url.openConnection();
            for(int i=0;;i++){
                // 返回第N个首部字段的值
                String headerField = urlConnection.getHeaderField(i);
                // 返回指定首部字段的值 不一定是有效值 必须判空
                String headerField1 = urlConnection.getHeaderField("content-type");

                if(headerField == null)break;
                // 返回第N个的首部的键
                System.out.println(urlConnection.getHeaderFieldKey(i)+ ":" + headerField);

                // 获取表示日期的首部字段，如果参数中解析不出来 就返回默认的0； expires,last-modified,date
                long expires = urlConnection.getHeaderFieldDate("expires", 0);
                System.out.println("转换后的过期时间："+new Date(expires));

                // 获取首部字段name 的值，转换成int ,如果失败 返回-1
                int headerFieldInt = urlConnection.getHeaderFieldInt("content-length", -1);
                System.out.println("内容长度是： " + headerFieldInt);
            }

        }catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public static void main(String[] args) {
        readHttpHead();
    }
}
